#include "mainwindow.h"
#include "ui_mainwindow.h"

#define RS_DEVICE "/dev/ttyUSB0" //串口名称
#define BAUDRATE B115200 //波特率设置

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/******************************************************************
 * 函数功能：打开串口
 * 输入参数：无
 * 返回值 true,false
 * ****************************************************************/
//void MainWindow::on_openButton_clicked()
bool MainWindow::on_openButton_clicked()
{
    struct termios setting;
    char data[10]={0xff,0xaa,0x03,0x08,0x00,0xff,0xaa,0x00,0x00,0x00};
    fd=open(RS_DEVICE,O_RDWR|O_NOCTTY);//以读写方式打开串口，不控制TTY
    if(fd==-1)
    {
        QMessageBox::warning(this, "open error", strerror(errno));
        goto openerr;
    }
    tcgetattr(fd, &setting);
    cfsetispeed(&setting, BAUDRATE);//115200
    cfsetospeed(&setting, BAUDRATE);
    cfmakeraw(&setting);
    setting.c_cflag|=CS8;       //8位
    setting.c_cflag|=CLOCAL;    //忽略DCD信号
    setting.c_cflag|=CREAD;     //启动接收装置
    setting.c_iflag|=IGNPAR;    //忽略奇偶

    setting.c_oflag=0;
    setting.c_lflag=0;

    setting.c_cc[VMIN]=0;
    setting.c_cc[VTIME]=100;//在规定时间（VTIME)内读取(VMIN)个字符
    tcflush(fd,TCIFLUSH);//清除所有队列在串口的输入与输出;
    tcsetattr(fd,TCSANOW,&setting);//把我们的设置写入termios

    monitor=new QSocketNotifier(fd,QSocketNotifier::Read,NULL);
    autoTimer=new QTimer;//不需要使用
    timer1=new QTimer;

    autoTimer->start(50);//显示扫描时间 100ms

    connect(monitor,SIGNAL(activated(int)),this,SLOT(readData()));
    //connect(autoTimer,SIGNAL(timeout()),this,SLOT(on_sendButon_clicked()));不需要使用
    connect(autoTimer,SIGNAL(timeout()),this,SLOT(updateData()));
    connect(this,SIGNAL(finished()),this,SLOT(closefd()));
    connect(timer1,SIGNAL(timeout()),this,SLOT(monitorSetEndable()));

    monitor->setEnabled(true);
/****************************************************
    ui->hexBox->setCheckState(Qt::Checked);
    ui->autoSend->setCheckState(Qt::Unchecked);
    ui->sendSpin->setValue(100);
    ui->sendInfo->clear();
    on_clearButton_clicked();
**********以上不用************************************
*****************************************************/
//    write(fd,data,10);

    return true;
    //设置波特率，数据位，parity，停止位，错误时的跳转到seterr关闭端口
seterr:
    ::close(fd);
openerr:
    return false;
}

/**************************************************************************
 * 函数功能：关闭串口并退出界面
 * 输入参数：无
 * 返回值  ：无
 * ************************************************************************/
void MainWindow::on_closeButton_clicked()
{
    if(fd!=-1)
        ::close(fd);
    autoTimer->stop();//定时发送不使用
    timer1->stop();
    delete monitor;
    delete autoTimer;//定时发送不使用
    delete timer1;
    this->close();
}

/*************************************************************************
 *
 *
 * ***********************************************************************/
void MainWindow::closefd()
{
    timer1->start(10);//串口启动间隔 9ms
    int top=0,checktemp=0;
    for(int i=0;i<66;i++)
    {
        if(0x55==buf[i])
        {
            top=i;
            break;
        }
    }
    for(int i=0;i<66;i++)
    {
        if(i+top<66)
            revbuf[i]=buf[i+top];
        else
            revbuf[i]=buf[i+top-66];
    }
    for(int i=0;i<6;i++)
    {
        switch (revbuf[i*11+1])
        {
        case 0x50:
            break;
        case 0x51:
            //0x55 0x51 加速度
            a[0]=(((revbuf[i*11+3]<<8)&0xff00)|(revbuf[i*11+2]&0x00ff))/32768.0*16;//g,9.8m/s^2
            a[1]=(((revbuf[i*11+5]<<8)&0xff00)|(revbuf[i*11+4]&0x00ff))/32768.0*16;//g,9.8m/s^2
            a[2]=(((revbuf[i*11+7]<<8)&0xff00)|(revbuf[i*11+6]&0x00ff))/32768.0*16;//g,9.8m/s^2
            a[3]=(((revbuf[i*11+9]<<8)&0xff00)|(revbuf[i*11+8]&0x00ff));//  ℃
            for(int t=0;t<3;t++)
            {
                if(a[t]>=16)
                {
                    a[t]=a[t]-32;
                }
                else
                {
                    a[t]=a[t]+0;
                }
            }
            //Temperature=a[3]/100.0; //0x55 0x51 0x52 0x53 0x54 温度℃
            break;
        case 0x52:
            //0x55 0x52 角速度
            w[0]=(((revbuf[i*11+3]<<8)&0xff00)|(revbuf[i*11+2]&0x00ff))/32768.0*2000;
            w[1]=(((revbuf[i*11+5]<<8)&0xff00)|(revbuf[i*11+4]&0x00ff))/32768.0*2000;
            w[2]=(((revbuf[i*11+7]<<8)&0xff00)|(revbuf[i*11+6]&0x00ff))/32768.0*2000;
            w[3]=(((revbuf[i*11+9]<<8)&0xff00)|(revbuf[i*11+8]&0x00ff));
            for(int t=0;t<3;t++)
            {
                if(w[t]>=2000)
                {
                    w[t]=w[t]-4000;
                }
                else
                {
                    w[t]=w[t]+0;
                }
            }
            Temperature=w[3]/100.0; //0x55 0x51 0x52 0x53 0x54 温度℃
            break;
        case 0x53:
            //0x55 0x53 角度
            Angle[0]=(((revbuf[i*11+3]<<8)&0xff00)|(revbuf[i*11+2]&0x00ff))/32768.0*180;
            Angle[1]=(((revbuf[i*11+5]<<8)&0xff00)|(revbuf[i*11+4]&0x00ff))/32768.0*180;
            Angle[2]=(((revbuf[i*11+7]<<8)&0xff00)|(revbuf[i*11+6]&0x00ff))/32768.0*180;
            Angle[3]=(((revbuf[i*11+9]<<8)&0xff00)|(revbuf[i*11+8]&0x00ff));
            for(int t=0;t<3;t++)
            {
                if(Angle[t]>=180)
                {
                    Angle[t]=Angle[t]-360;
                }
            else
                {
                    Angle[t]=Angle[t]+0;
                }
            }
            //Temperature=Angle[3]/100.0; //0x55 0x51 0x52 0x53 0x54 温度℃
            break;
        case 0x54:
            //0x55 0x54 磁场
            h[0]=(((revbuf[i*11+3]<<8)&0xff00)|(revbuf[i*11+2]&0x00ff));
            h[1]=(((revbuf[i*11+5]<<8)&0xff00)|(revbuf[i*11+4]&0x00ff));
            h[2]=(((revbuf[i*11+7]<<8)&0xff00)|(revbuf[i*11+6]&0x00ff));
            h[3]=(((revbuf[i*11+9]<<8)&0xff00)|(revbuf[i*11+8]&0x00ff));
            for(int t=0;t<3;t++)
            {
                if(h[t]>=32768)
                {
                    h[t]=h[t]-32768;
                }
                else
                {
                    h[t]=h[t]+0;
                }
            }
            //Temperature=h[3]/100.0; //0x55 0x51 0x52 0x53 0x54 温度℃
            break;
        case 0x55:
            //0x55 0x55  端口
            Port[0]=(((revbuf[i*11+3]<<8)&0xff00)|(revbuf[i*11+2]&0x00ff));
            Port[1]=(((revbuf[i*11+5]<<8)&0xff00)|(revbuf[i*11+4]&0x00ff));
            Port[2]=(((revbuf[i*11+7]<<8)&0xff00)|(revbuf[i*11+6]&0x00ff));
            Port[3]=(((revbuf[i*11+9]<<8)&0xff00)|(revbuf[i*11+8]&0x00ff));
            break;
        case 0x56:
            //0x55 0x56  气压  高度
            Pressure=(((revbuf[i*11+5]<<24)&0xff000000)|((revbuf[i*11+4]<<16)&0x00ff0000)|((revbuf[i*11+3]<<8)&0x0000ff00)|(revbuf[i*11+2]&0x000000ff));
            //Altitude=(((revbuf[i*11+9]<<24)&0xff000000)|((revbuf[i*11+8]<<16)&0x00ff0000)|((revbuf[i*11+7]<<8)&0x0000ff00)|(revbuf[i*11+6]&0x000000ff))/100.0;
            break;
        case 0x57:
            //经纬度
            break;
        case 0x58:
            //地速
            break;
        case 0x59:
            //四元素
            break;
        case 0x5A:
            //卫星定位精度
            break;
        default:
            break;
        }
    }
}
/*************************************************************************
 *
 *
 * ***********************************************************************/
void MainWindow::updateData() //数据更新
{
    int byteLen=0;
    char *m_pData;
    byteLen=sizeof(buf);
    QDateTime time =QDateTime::currentDateTime();//获得系统现在的时间
    //QString str1=time.toString("yyyy-MM-dd hh:mm:ss ddd");//设置显示格式
    QString str1=time.toString("hh:mm:ss");//设置显示格式
    ui->lineEdit->setText(str1);
    ui->lineEdit_2->setText(QString::number(byteLen));
    //ui->lineEdit_2->setText(QString::number(top));
    ui->lineEdit_3->setText(QString::number(a[0]));//x轴加速度
    ui->lineEdit_4->setText(QString::number(a[1]));//y轴加速度
    ui->lineEdit_5->setText(QString::number(a[2]));//z轴加速度
    ui->lineEdit_6->setText(QString::number(w[0]));//x轴角速度
    ui->lineEdit_7->setText(QString::number(w[1]));//y轴角速度
    ui->lineEdit_8->setText(QString::number(w[2]));//z轴角速度
    ui->lineEdit_9->setText(QString::number(Angle[0]));//x轴角度
    ui->lineEdit_10->setText(QString::number(Angle[1]));//y轴角度
    ui->lineEdit_11->setText(QString::number(Angle[2]));//z轴角度
    ui->lineEdit_12->setText(QString::number(h[0]));//x轴磁场
    ui->lineEdit_13->setText(QString::number(h[1]));//y轴磁场
    ui->lineEdit_14->setText(QString::number(h[2]));//z轴磁场
    ui->lineEdit_15->setText(QString::number(Temperature));//温度
    ui->lineEdit_16->setText(QString::number(Pressure));//textChanged 气压
    ui->lineEdit_17->setText(QString::number(Altitude));//高度
    m_pData=revbuf;
    for(int i=0;i<66;i++)
    {
        QString s;
        s.sprintf("0x%02x, ",(unsigned char)*m_pData);
        revData+=s;
        m_pData=m_pData+1;
        s.clear();
    }
    ui->revInfo->setText(revData);
    revData.clear();
}

/*************************************************************************
 *
 *
 * ***********************************************************************/
void MainWindow::readData() //读出数据
{
    int ret;
    monitor->setEnabled(false);
    //ret=read(fd,buf,sizeof(buf));
    ret=read(fd,buf,66);
    buf[ret]=0;
    emit finished();
}

/************************************************************************
 *
 *
 * **********************************************************************/
void MainWindow::monitorSetEndable()
{
    timer1->stop();
    monitor->setEnabled(true);
}

/***********************************************************************
 *
 *
 * *********************************************************************/
void MainWindow::on_highButton_clicked()
{
//    int ret;
    char data[10]={0xff,0xaa,0x01,0x03,0x00,0xff,0xaa,0x00,0x00,0x00};
//    ret=write(fd,data,5);
    write(fd,data,10);
}
